package net.xiaoyu233.mitemod.miteite.entity;

import net.minecraft.*;
import net.xiaoyu233.mitemod.miteite.item.Items;
import net.xiaoyu233.mitemod.miteite.util.ParticleUtils;

import java.util.*;

public class EntityInfernalOverlord extends EntityZombie  {
    private static final double BASE_ATTACK_DAMAGE = 12;
    private static final int FENCE_HEIGHT = 5; // 栅栏高度
    private static boolean InfernalOverlordDefeated = false;
    private double baseAttackDamage = BASE_ATTACK_DAMAGE;
    private boolean ritualTriggered = false;
    private final List<Entity> ritualZombies = new ArrayList<>();
    private final List<int[]> generatedFences = new ArrayList<>(); //铁栅栏坐标
    private int brandCooldown = 0;          // 技能冷却计时器
    private final Map<EntityPlayer, Integer> markedPlayers = new HashMap<>(); // 被标记玩家及剩余时间、
    private int healingTimer = 0;
    private boolean isRitualActive = false;
    private final Map<EntityPlayer, Float> threatMap = new HashMap<>();
    private EntityPlayer currentTarget;
    private int threatUpdateTimer = 0; //周期切换目标
    private int combatTimer = 0;  //仇恨值脱战
    private int groundSmashCooldown = 0;//烈焰震地波


    public int DATA_OBJ_IS_enlarge;


    public EntityInfernalOverlord(World par1World) {
        super(par1World);
        initializeBoss();
        this.setHealth(this.getMaxHealth());

    }

    @Override
    protected void entityInit() {
        super.entityInit();
        this.DATA_OBJ_IS_enlarge = this.dataWatcher.addObject(this.dataWatcher.getNextAvailableId(), (byte) 0);
    }

    private boolean isenlarge() {
        return this.dataWatcher.getWatchableObjectByte(this.DATA_OBJ_IS_enlarge) != 0;
    }

    @Override
    public String getEntityName() {
        return "地狱领主";
    }

    public static boolean isInfernalOverlordDefeated() {
        return InfernalOverlordDefeated;
    }

    private void initializeBoss() {

        // 初始属性设置
        this.setEntityAttribute(GenericAttributes.movementSpeed, 0.3f);
        this.setEntityAttribute(GenericAttributes.maxHealth, 200f);
        this.setEntityAttribute(GenericAttributes.attackDamage, BASE_ATTACK_DAMAGE);
        this.setPosition(posX, posY + 1.0, posZ); // 防止卡入地下
        this.setCurrentItemOrArmor(0, new ItemStack(Items.VIBRANIUM_WAR_HAMMER, 1).randomizeForMob(this, true));
        this.setCurrentItemOrArmor(1, new ItemStack(Items.VIBRANIUM_HELMET, 1).randomizeForMob(this, true));
        this.setCurrentItemOrArmor(2, new ItemStack(Items.VIBRANIUM_CHESTPLATE, 1).randomizeForMob(this, true));
        this.setCurrentItemOrArmor(3, new ItemStack(Items.VIBRANIUM_LEGGINGS, 1).randomizeForMob(this, true));
        this.setCurrentItemOrArmor(4, new ItemStack(Items.VIBRANIUM_BOOTS, 1).randomizeForMob(this, true));
        InfernalOverlordDefeated = false;
    }



    @Override
    protected void tryDamageArmor(DamageSource damage_source, float amount, EntityDamageResult result) {
    }

    public boolean isComfortableInLava() {
        return true;
    }

    public boolean getCanSpawnHere(boolean perform_light_check) {
        return true;
    }

    @Override
    public boolean handleLavaMovement() {
        return false;
    }

    @Override
    public boolean handleWaterMovement() {
        return false;
    }

    public boolean canBeDisarmed() {
        return false;
    }

    public boolean canCatchFire() {
        return false;
    }

    public boolean isPushedByWater() {
        return false;
    }


    @Override
    public boolean canNeverPickUpItem(Item item) {
        return true;
    }

    public boolean canBeKnockedBack() {
        return false;
    }



    @Override
    public void onUpdate() {
        super.onUpdate();
        if (!worldObj.isRemote) {
            if (getAttackTarget() != null) {
                if (!ritualTriggered && getHealth() / getMaxHealth() <= 0.5f) {
                    startSacrificialRitual();
                    ritualTriggered = true;
                }

                if (isRitualActive) {
                    if (++healingTimer >= 40) { // 5秒（20 ticks/秒 * 5 = 100）
                        performRitualHealing();

                        healingTimer = 0;
                    }
                }

                if (++threatUpdateTimer >= 40) {
                    selectHighestThreatTarget();
                    threatUpdateTimer = 0;
                }
                if (++combatTimer >= 600) { // 30秒无战斗

                    threatMap.clear();
                    currentTarget = null;
                    this.setTarget(null);
                    combatTimer = 0;
                    if (this.getHealth() < this.getMaxHealth()) {
                        this.heal(this.getMaxHealth());
                    }
                    ritualTriggered = false;
                    for (Entity zombie : ritualZombies) {
                        zombie.setDead();
                    }
                    ritualZombies.clear();
                    clearIronBars();
                }
                if (++brandCooldown >= 20 * 15) { // 每10秒触发一次（20 ticks/秒 * 10）
                    brandCooldown = 0;
                    markRandomPlayer(); // 标记随机玩家
                }
                if (++groundSmashCooldown >= 20 * 10) {
                    groundSmashCooldown = 0;
                    performGroundSmash();
                }
                updateMarkedPlayers();
            }
        }
    }

    private void performGroundSmash() {
        worldObj.playSoundAtEntity(this, "mob.ghast.fireball", 2.0F, 0.5F);
        // === 强化地面火焰扩散环 ===
        final double RADIUS = 8.0;          // 冲击波半径
        final int RING_PARTICLES = 200;     // 粒子总数增加
        final double SPREAD_SPEED = 0.2;    // 扩散速度提升

        // 1. 地面岩浆冲击波（三层扩散环）
        for (int wave = 0; wave < 3; wave++) { // 新增三层冲击波
            double waveOffset = wave * 1.5;    // 每层间隔1.5格
            for (int i = 0; i < RING_PARTICLES; i++) {
                double angle = Math.toRadians(i * 1.8); // 更密集的角度分布
                double dx = Math.cos(angle) * (RADIUS - waveOffset);
                double dz = Math.sin(angle) * (RADIUS - waveOffset);

                // 使用岩浆粒子+火焰粒子混合
                int particleType = (i % 3 == 0) ?
                        EnumParticle.lava.ordinal() :  // 60%岩浆粒子
                        EnumParticle.flame.ordinal();  // 40%火焰粒子

                // 动态速度（外层更快）
                double speedMultiplier = 1.0 + (wave * 0.3);
                double vx = Math.cos(angle) * SPREAD_SPEED * speedMultiplier;
                double vz = Math.sin(angle) * SPREAD_SPEED * speedMultiplier;

                ParticleUtils.spawnParticle(
                        worldObj, particleType,
                        posX + dx, posY + 0.1, posZ + dz, // 紧贴地面
                        vx,
                        0.05 + rand.nextDouble(),   // 轻微随机上升
                        vz
                );
            }
        }

        // 2. 随机地面爆裂火花（增强地面细节）
        for (int i = 0; i < 50; i++) {
            double angle = rand.nextDouble() * Math.PI * 2;
            double distance = rand.nextDouble() * RADIUS;
            double dx = Math.cos(angle) * distance;
            double dz = Math.sin(angle) * distance;

            ParticleUtils.spawnParticle(
                    worldObj, EnumParticle.spell.ordinal(),
                    posX + dx, posY + 0.5, posZ + dz,
                    (rand.nextDouble() - 0.5) * 0.3,
                    rand.nextDouble() * 0.5,
                    (rand.nextDouble() - 0.5) * 0.3
            );
        }

        // 3. 中心冲击波光效（保留核心闪光）
        for (int i = 0; i < 20; i++) {
            ParticleUtils.spawnParticle(
                    worldObj, EnumParticle.reddust.ordinal(),
                    posX, posY + 1, posZ,
                    (rand.nextDouble() - 0.5) * 0.8,
                    rand.nextDouble() * 0.8,
                    (rand.nextDouble() - 0.5) * 0.8
            );
        }

        List<EntityPlayer> players = worldObj.getEntitiesWithinAABB(EntityPlayer.class, boundingBox.expand(RADIUS, 3, RADIUS));
        for (EntityPlayer player : players) {
            // 击退玩家并造成伤害
            player.attackEntityFrom(new Damage(DamageSource.causeMobDamage(this), 4f));
            player.addVelocity(0, 1, 0); // 轻微击飞
        }
    }

    private void markRandomPlayer() {
        List<EntityPlayer> nearbyPlayers = worldObj.getEntitiesWithinAABB(EntityPlayer.class,
                boundingBox.expand(20, 10, 20));
        if (!nearbyPlayers.isEmpty()) {
            EntityPlayer target = nearbyPlayers.get(rand.nextInt(nearbyPlayers.size()));
            markedPlayers.put(target, 100); // 5秒后爆炸（100 ticks）
            // 播放标记音效与粒子
            worldObj.playSoundAtEntity(target, "mob.ghast.fireball", 1.0F, 0.5F);
            ParticleUtils.spawnParticleLine(worldObj,
                    posX, posY + 2, posZ,
                    target.posX, target.posY + 1, target.posZ,
                    EnumParticle.reddust.ordinal(), 30, 0.9, 0.1, 0.1);
        }
    }

    private void updateMarkedPlayers() {
        Iterator<Map.Entry<EntityPlayer, Integer>> iterator = markedPlayers.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<EntityPlayer, Integer> entry = iterator.next();
            EntityPlayer player = entry.getKey();
            int remainingTicks = entry.getValue() - 1;

            // 显示倒计时粒子
            if (remainingTicks > 0) {
                ParticleUtils.spawnParticle(worldObj, EnumParticle.flame.ordinal(),
                        player.posX, player.posY + 2, player.posZ, 0, 0.1, 0);
                markedPlayers.put(player, remainingTicks);
            } else {
                // 触发爆炸并生成燃烧区域
                triggerBrandExplosion(player);
                iterator.remove();
            }
        }
    }

    private void triggerBrandExplosion(EntityPlayer player) {
        // 爆炸效果
        worldObj.createExplosion(this, player.posX, player.posY, player.posZ, 1.0F, 1f, false);
        worldObj.playSoundAtEntity(player, "random.explode", 2.0F, 0.8F);
        // 生成燃烧区域（5x5火焰方块，持续8秒）
        for (int dx = -2; dx <= 2; dx++) {
            for (int dz = -2; dz <= 2; dz++) {
                int x = (int) player.posX + dx;
                int z = (int) player.posZ + dz;
                int y = worldObj.getHeightValue(x, z);
                if (worldObj.isAirBlock(x, y, z) && worldObj.getBlock(x, y - 1, z).is_normal_cube) {
                    worldObj.setBlock(x, y, z, Block.fire.blockID, 0, 0);
                    worldObj.scheduleBlockUpdate(x, y, z, Block.fire.blockID, 160); // 8秒后熄灭
                }
            }
        }
    }    // 触发爆炸与燃烧区域

    private void startSacrificialRitual() {
        final int ZOMBIE_COUNT = 8; // 僵尸数量
        final double MAX_SPAWN_RADIUS = 12.0; // 最大生成半径
        // 生成仪式僵尸
        for (int i = 0; i < ZOMBIE_COUNT; i++) {
            EntityRitualZombie zombie = new EntityRitualZombie(worldObj);

            double angle = rand.nextDouble() * Math.PI * 2;
            double radius = rand.nextDouble() * MAX_SPAWN_RADIUS;

            // 计算生成坐标
            double x = posX + Math.cos(angle) * radius;
            double z = posZ + Math.sin(angle) * radius;
            int y = worldObj.getHeightValue((int) x, (int) z); // 获取地面高度

            zombie.setPosition(x, y, z);
            zombie.rotationYaw = rand.nextFloat() * 360.0f; // 随机朝向
            worldObj.spawnEntityInWorld(zombie);
            ritualZombies.add(zombie);
            ParticleUtils.spawnParticle(worldObj, EnumParticle.flame.ordinal(),
                    x, y + 1, z, 0, 0.1, 0);
        }
        worldObj.scheduleBlockUpdate(
                (int) posX, (int) posY, (int) posZ,
                Block.fenceIron.blockID,
                10 // 2 ticks延迟
        );
        generateIronBarsRing();
        isRitualActive = true;
        worldObj.playSoundEffect(posX, posY + 1, posZ, "mob.enderdragon.growl", 5.0F, 0.5F);
    }

    private void generateIronBarsRing() {
        List<Entity> allEntities = new ArrayList<>(ritualZombies);
        allEntities.add(this);

        // 1. 计算所有实体的实际包围盒
        AxisAlignedBB totalBoundingBox = null;
        for (Entity entity : allEntities) {
            AxisAlignedBB entityBox = entity.boundingBox.expand(1.0, 0, 1.0); // 每个实体周围保留1格安全距离
            if (totalBoundingBox == null) {
                totalBoundingBox = entityBox;
            } else {
                totalBoundingBox = totalBoundingBox.func_111270_a(entityBox);

            }
        }

        if (totalBoundingBox == null) return;

        // 3. 生成矩形包围栅栏（非圆形）
        int minX = (int) Math.floor(totalBoundingBox.minX - 1);
        int maxX = (int) Math.ceil(totalBoundingBox.maxX + 1);
        int minZ = (int) Math.floor(totalBoundingBox.minZ - 1);
        int maxZ = (int) Math.ceil(totalBoundingBox.maxZ + 1);

        // 4. 生成四边栅栏
        for (int x = minX; x <= maxX; x++) {
            for (int z = minZ; z <= maxZ; z++) {
                // 判断是否为边界层（外层或内层）
                boolean isOuterEdge =
                        x == minX || x == maxX ||
                                z == minZ || z == maxZ;
                boolean isInnerEdge =
                        x == minX + 1 || x == maxX - 1 ||
                                z == minZ + 1 || z == maxZ - 1;

                if (isOuterEdge || isInnerEdge) { // 双层检测
                    for (int yOffset = 0; yOffset < FENCE_HEIGHT; yOffset++) {
                        int yPos = (int) posY + yOffset;
                        if (worldObj.isAirBlock(x, yPos, z)) {
                            worldObj.setBlock(x, yPos, z, Block.fenceIron.blockID);
                            generatedFences.add(new int[]{x, yPos, z}); // 记录坐标
                        }
                    }
                }
            }
        }

        // 5. 额外加固四角（可选）
        int[][] corners = {{minX, minZ}, {minX, maxZ}, {maxX, minZ}, {maxX, maxZ}};
        for (int[] corner : corners) {
            for (int dx = -1; dx <= 1; dx++) {
                for (int dz = -1; dz <= 1; dz++) {
                    for (int yOffset = 0; yOffset < FENCE_HEIGHT + 2; yOffset++) {
                        int xPos = corner[0] + dx;
                        int zPos = corner[1] + dz;
                        int yPos = (int) posY + yOffset;
                        if (worldObj.isAirBlock(xPos, yPos, zPos)) {
                            worldObj.setBlock(xPos, yPos, zPos, Block.fenceIron.blockID);
                            generatedFences.add(new int[]{xPos, yPos, zPos});
                        }
                    }
                }
            }
        }
    }

    private void clearIronBars() {
        Iterator<int[]> iterator = generatedFences.iterator();
        while (iterator.hasNext()) {
            int[] pos = iterator.next();
            if (worldObj.getBlockId(pos[0], pos[1], pos[2]) == Block.fenceIron.blockID) {
                worldObj.setBlockToAir(pos[0], pos[1], pos[2]); // 清除方块
            }
            iterator.remove();
        }
        generatedFences.clear();
    }

    private void performRitualHealing() {
        // 清理死亡僵尸
        Iterator<Entity> iterator = ritualZombies.iterator();
        while (iterator.hasNext()) {
            Entity zombie = iterator.next();
            if (zombie.isDead) iterator.remove();
        }
        // 每存活一只恢复2点生命
        int aliveCount = ritualZombies.size();
        this.heal(aliveCount * 1.5f);

        // 检测是否解除仪式
        if (getHealth() / getMaxHealth() > 0.9f) {
            endRitual(true);
            this.dataWatcher.updateObject(this.DATA_OBJ_IS_enlarge,(byte) 1);
            this.setSize(0.6F * 2, 1.8F * 2); // 宽度和高度都变为原来的两倍
        }
        if (aliveCount > 0) {
            spawnHealingBeam(posX, posY, posZ);
            baseAttackDamage = BASE_ATTACK_DAMAGE + aliveCount;
            this.setEntityAttribute(GenericAttributes.attackDamage, baseAttackDamage);
        } else {
            baseAttackDamage = BASE_ATTACK_DAMAGE;
            this.setEntityAttribute(GenericAttributes.attackDamage, baseAttackDamage);
        }
    }


    private void spawnHealingBeam(double x, double y, double z) {
        for (Entity zombie : ritualZombies) {
            if (!zombie.isDead) {
                ParticleUtils.spawnParticleLine(
                        worldObj,
                        zombie.posX, zombie.posY + 1.2, zombie.posZ,
                        x, y + 2.5, z,
                        21, 20, 0, 0, 0
                );
            }
        }
    }

    private void endRitual(boolean success) {
        isRitualActive = false;
        // 清除所有仪式僵尸
        for (Entity zombie : ritualZombies) {
            zombie.setDead();
        }
        ritualZombies.clear();
        // 移除铁栅栏（可选）
        clearIronBars();
        // 可根据需求添加方块清除逻辑
        if (!success) {
            baseAttackDamage = BASE_ATTACK_DAMAGE + 3;
            this.setEntityAttribute(GenericAttributes.attackDamage, baseAttackDamage);
        }

    }

    private void updateThreat(EntityPlayer player, float amount) {
        // 更新仇恨值，叠加新值并衰减旧值
        float currentThreat = threatMap.getOrDefault(player, 0f);
        currentThreat = currentThreat * 0.9f + amount; // 旧值衰减10%
        threatMap.put(player, currentThreat);

        // 如果玩家死亡或离线，移除仇恨
        if (player.isDead || !player.isEntityAlive()) {
            threatMap.remove(player);
        }
    }

    private void selectHighestThreatTarget() {
        EntityPlayer highestPlayer = null;
        float maxThreat = 0;
        for (Map.Entry<EntityPlayer, Float> entry : threatMap.entrySet()) {
            if (entry.getValue() > maxThreat) {
                maxThreat = entry.getValue();
                highestPlayer = entry.getKey();
            }
        }
        // 切换目标逻辑：新目标仇恨需超过当前目标20%以上
        if (highestPlayer != null && (currentTarget == null ||
                maxThreat > threatMap.getOrDefault(currentTarget, 0f) * 1.2f)) {
            currentTarget = highestPlayer;
            this.setTarget(currentTarget);
            sendThreatShiftMessage(highestPlayer); // 发送仇恨转移提示
        }
    }

    private void sendThreatShiftMessage(EntityPlayer newTarget) {
        String message = "§c地狱领主将怒火转向了 " + newTarget.getEntityName() + "!";
        // 向所有玩家广播消息
        for (Object o : worldObj.playerEntities) {
            if (o instanceof EntityPlayer) {
                EntityPlayer player = (EntityPlayer) o;
                player.sendChatToPlayer(ChatMessage.createFromText(message));
            }
        }
        // 播放警示音效
        worldObj.playSoundAtEntity(this, "random.orb", 1.0F, 0.5F);
    }

    @Override
    public EntityDamageResult attackEntityFrom(Damage damage) {
        if (getHealth() / getMaxHealth() <= 0.4f && rand.nextFloat() < 0.1f) {
            teleportRandomly();
        }
//        if (damage.getSource().damageType.equals("player") || damage.getSource().damageType.equals("mob")) {
//            if (damage.getSource().getResponsibleEntity() instanceof EntityPlayer) {
//                EntityPlayer player = ((EntityPlayer) damage.getSource().getResponsibleEntity());
//                this.setTarget(player);
//            }
//        }
        Entity sourceEntity = damage.getSource().getResponsibleEntity();
        if (sourceEntity instanceof EntityPlayer) {
            EntityPlayer attacker = (EntityPlayer) sourceEntity;
            // 根据伤害量增加仇恨（1伤害=1仇恨）
            updateThreat(attacker, damage.getAmount());
        }
        return super.attackEntityFrom(damage);
    }

    private void teleportRandomly() {
        // 计算随机传送位置
        double newX = posX + (rand.nextDouble() - 0.5) * 8; // 4格范围
        double newY = posY;
        double newZ = posZ + (rand.nextDouble() - 0.5) * 8;

        // 确保传送位置安全（不卡在方块里）
        newY = worldObj.getHeightValue((int) newX, (int) newZ);

        // 执行传送
        this.setPosition(newX, newY, newZ);

        // 播放特效和音效
        worldObj.playSoundAtEntity(this, "mob.endermen.portal", 1.0F, 1.0F);
        for (int i = 0; i < 32; i++) {
            ParticleUtils.spawnParticle(worldObj, 17,
                    posX + (rand.nextDouble() - 0.5) * 2,
                    posY + rand.nextDouble() * 3,
                    posZ + (rand.nextDouble() - 0.5) * 2,
                    0, 0, 0);
        }

    }

    @Override
    public void onDeath(DamageSource par1DamageSource) {
        for (Entity zombie : ritualZombies) {
            zombie.setDead();
        }
        ritualZombies.clear();
        clearIronBars();
        InfernalOverlordDefeated = true;
    }

    @Override
    public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) {
        super.writeEntityToNBT(par1NBTTagCompound);
        par1NBTTagCompound.setBoolean("ritualTriggered", this.ritualTriggered);
        par1NBTTagCompound.setBoolean("isRitualActive", this.isRitualActive);
        par1NBTTagCompound.setBoolean("InfernalOverlordDefeated", InfernalOverlordDefeated);
        par1NBTTagCompound.setBoolean("Boosted", this.isenlarge());
    }

    @Override
    public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) {
        super.readEntityFromNBT(par1NBTTagCompound);
        this.ritualTriggered = par1NBTTagCompound.getBoolean("ritualTriggered");
        this.isRitualActive = par1NBTTagCompound.getBoolean("isRitualActive");
        this.InfernalOverlordDefeated = par1NBTTagCompound.getBoolean("InfernalOverlordDefeated");
        boolean boosted = par1NBTTagCompound.getBoolean("Boosted");
        this.dataWatcher.updateObject(this.DATA_OBJ_IS_enlarge, (byte) (boosted ? 1 : 0));
        if (boosted) {
            this.setSize(0.6F * 2, 1.8F * 2);
        }
    }

    @Override
    protected void dropFewItems(boolean recently_hit_by_player, DamageSource damage_source) {
        if (recently_hit_by_player) {
            this.dropItem(Items.minePocket);
            this.dropItemStack(new ItemStack(Item.diamond, rand.nextInt(15) + 6));
            this.dropItemStack(new ItemStack(Item.emerald, rand.nextInt(10) + 6));
            this.dropItemStack(new ItemStack(Items.VIBRANIUM_INGOT, rand.nextInt(2) + 2));
            this.dropItemStack(new ItemStack(Items.ingotIron, rand.nextInt(8) + 2));

        }
    }
}
